<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html>
<head>
<title>Spinner widget</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Android, programming, Spinner widget, tutorial, 
Java, mobile development">
<meta name="description" content="In this chapter of the Android tutorial, we present
spinner widgets.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container2">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content2">


<a href="/" title="Home">Home</a>&nbsp;
<a href=".." title="Home">Contents</a>


<h1>Spinner widget</h1>


<p>
In this chapter of the Android development tutorial we will present a spinner 
widget. 
</p>

<div class="big_hor">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* big_horizontal */
google_ad_slot = "2904953388";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
A spinner widget enables a user to select an item from a list of options. 
In the normal state it shows the currently selected item. Clicking on the
spinner widget shows a dropdown menu with all available items. The
user can choose a new one from the list. The <code>Spinner</code> class is 
used to create a spinner widget. 
</p>

<p>
The Spinner widget can be populated in the XML file. Or it can be programatically
filled. In the latter case we need an Adapter class to populate the Spinner widget. 
An adapter is a bridge between a Spinner and its data.
</p>

<h2>Spinner I</h2>
 
<p>
In the first example we have a Spinner widget whose items are defined in an XML file.
</p>

<div class="codehead">AndroidManifest.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.finish"
      android:versionCode="1"
      android:versionName="1.0"&gt;
 &lt;application android:label="@string/app_name" android:icon="@drawable/ic_launcher"&gt;
    &lt;activity android:name="MainActivity"
                android:label="@string/app_name"&gt;
        &lt;intent-filter&gt;
            &lt;action android:name="android.intent.action.MAIN" /&gt;
            &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
        &lt;/intent-filter&gt;
    &lt;/activity&gt;
 &lt;/application&gt;
&lt;/manifest&gt;
</pre>

<p>
This is the manifest file for the program.
</p>

<div class="codehead">main.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
   &lt;Spinner
        android:id="@+id/spn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/dlangs"
        android:layout_marginTop="10dip"
        android:prompt="@string/spn_title" /&gt;

   &lt;TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" 
      android:layout_marginTop="10dip"
      /&gt;        
        
&lt;/LinearLayout&gt;
</pre>

<p>
In the <i>main.xml</i> layout file, we have a Spinner and a TextView. 
The <i>android:entries="@array/dlangs"</i> attribute defines a XML resource 
that provides an array of strings. The strings are written in the <i>strings.xml</i>
file. 
</p>

<div class="codehead">strings.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string name="app_name"&gt;Spinner&lt;/string&gt;
    &lt;string name="spn_title"&gt;Choose a language&lt;/string&gt;
    
    &lt;string-array name="dlangs"&gt;
        &lt;item&gt;Python&lt;/item&gt;
        &lt;item&gt;PHP&lt;/item&gt;
        &lt;item&gt;Perl&lt;/item&gt;
        &lt;item&gt;Tcl&lt;/item&gt;
        &lt;item&gt;Ruby&lt;/item&gt;
    &lt;/string-array&gt;    
    
&lt;/resources&gt;
</pre>

<p>
In the <i>strings.xml</i> file we have the elements of the string array. 
These are displayed when we click on the Spinner widget. 
</p>

<div class="codehead">MainActivity.java</div>
<pre class="code">
package com.zetcode.spinner;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener 
{
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.tvId);

        Spinner spn = (Spinner) findViewById(R.id.spn);
        spn.setOnItemSelectedListener(this);
    }

    @Override
    public void onItemSelected(AdapterView&lt;?&gt; parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView&lt;?&gt; arg0) 
    {      
      tv.setText("");
    }
}
</pre>

<p>
The selected item from the Spinner widget is displayed in the TextView widget. 
</p>

<pre class="explanation">
public class MainActivity extends Activity implements OnItemSelectedListener 
</pre>

<p>
The MainActivity class implements the <code>OnItemSelectedListener</code>. 
The class must now implement two methods. The <code>onItemSelected()</code> 
and <code>onNothingSelected()</code> methods.
</p>

<pre class="explanation">
Spinner spn = (Spinner) findViewById(R.id.spn);
spn.setOnItemSelectedListener(this);
</pre>

<p>
These two lines get the reference to the Spinner widget and set
the OnItemSelectedListener for it.
</p>

<pre class="explanation">
@Override
public void onItemSelected(AdapterView&lt;?&gt; parent, View v, int pos, long id) 
{
    String item = parent.getItemAtPosition(pos).toString();
    tv.setText(item);
}
</pre>

<p>
In the <code>onItemSelected()</code> method we get the currently selected Spinner item
with the <code>getItemAtPosition()</code>. The item is transformed to a string and set 
to the TextView.
</p>

<img src="/img/java/android/spinner.png" alt="Spinner widget">
<div class="figure">
Figure: Spinner widget
</div>


<h2>Spinner II</h2>
 
<p>
In the second spinner example, we will define our list of spinner elements
programatically. For this we will use the <code>ArrayAdapter</code> in conjunction with
the <code>ArrayList</code>. 
</p>

<p>
An Adapter design pattern is used by Android platform to work with the Spinner widget.
The <code>ArrayAdapter</code> is an intermediary between the data source and the
data view. In this case the data source is the ArrayList and the view is the Spinner
widget. Using an adapter we are decoupling our code. 
</p>

<div class="codehead">AndroidManifest.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.toast"
      android:versionCode="1"
      android:versionName="1.0"&gt;
    &lt;application android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher"&gt;
        &lt;activity android:name="MainActivity"
                  android:label="@string/app_name"&gt;
            &lt;intent-filter&gt;
                &lt;action android:name="android.intent.action.MAIN" /&gt;
                &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
    &lt;/application&gt;
&lt;/manifest&gt;
</pre>

<p>
This is the manifest file.
</p>

<div class="codehead">main.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    &gt;
    
  &lt;Spinner
      android:id="@+id/spnId"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dip" 
      android:prompt="@string/spn_title" /&gt;    
      
  &lt;TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dip"  /&gt;
    
&lt;/LinearLayout&gt;
</pre>

<p>
In the <i>main.xml</i> file we have two widgets. The Spinner
and the TextView widget. This time we do not define the
array data entries for the Spinner.
</p>

<div class="codehead">strings.xml</div>
<pre class="code">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;resources&gt;
    &lt;string name="app_name"&gt;Spinner2&lt;/string&gt;
    &lt;string name="spn_title"&gt;Choose a language&lt;/string&gt;
&lt;/resources&gt;
</pre>

<p>
This is the <i>strings.xml</i> resource file. 
</p>


<div class="codehead">MainActivity.java</div>
<pre class="code">
package com.zetcode.spinner2;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener
{
    private TextView tv;
    private Spinner spn;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setup();
    }

    public void setup()
    {
        tv = (TextView) findViewById(R.id.tvId);
   
        spn = (Spinner) findViewById(R.id.spnId);
        fillSpinner(spn);
        spn.setOnItemSelectedListener(this);
    }

    public void fillSpinner(Spinner spn) 
    {
        List&lt;String&gt; lst = new ArrayList&lt;String&gt;();
        lst.add("Python");
        lst.add("PHP");
        lst.add("Perl");
        lst.add("Tcl");
        lst.add("Ruby");
        
        ArrayAdapter&lt;String&gt; da = new ArrayAdapter&lt;String&gt;(this,
                android.R.layout.simple_spinner_item, lst);
        da.setDropDownViewResource(android.R.layout.simple_spinner_item);

        spn.setAdapter(da);
    }

    @Override
    public void onItemSelected(AdapterView&lt;?&gt; parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView&lt;?&gt; arg0) 
    {      
      tv.setText("");
    }
}
</pre>

<p>
In the MainActivity.java source file we fill the Spinner widget with data and 
implement the OnItemSelectedListener for the widget.
</p>

<pre class="explanation">
spn = (Spinner) findViewById(R.id.spnId);
fillSpinner(spn);
</pre>

<p>
We get the reference to the <code>Spinner</code> widget and call the fillSpinner() method
to populate it with data. 
</p>

<pre class="explanation">
List&lt;String&gt; lst = new ArrayList&lt;String&gt;();
lst.add("Python");
lst.add("PHP");
lst.add("Perl");
lst.add("Tcl");
lst.add("Ruby");
</pre>

<p>
An <code>ArrayList</code> is created and filled with strings. 
</p>

<pre class="explanation">
ArrayAdapter&lt;String&gt; da = new ArrayAdapter&lt;String&gt;(this,
        android.R.layout.simple_spinner_item, lst);
</pre>

<p>
The instance of the <code>ArrayAdapter</code> is created. It takes the ArrayList
as a parameter. 
</p>

<pre class="explanation">
da.setDropDownViewResource(android.R.layout.simple_spinner_item);
</pre>

<p>
This line determines the look of the dropdown menu of the Spinner widget.
This one is a dropdown without radio buttons. A spinner with the
<code>android.R.layout.simple_spinner_dropdown_item</code> defined has
radio buttons in its rows. 
</p>

<pre class="explanation">
spn.setAdapter(da);
</pre>

<p>
The adapter is set for the Spinner widget.
</p>

<img src="/img/java/android/spn_dropdown.png" alt="Spinner dropdown menu">
<div class="figure">
Figure: Spinner dropdown menu
</div>

<p>
In this chapter of the Android development tutorial, we have written about
a spinner widget. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div>
<br> 



<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified October 29, 2012  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

